package com.atguigu.daijia.map.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.map.service.MapService;
import com.atguigu.daijia.model.form.map.CalculateDrivingLineForm;
import com.atguigu.daijia.model.vo.map.DrivingLineVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class MapServiceImpl implements MapService {

    @Resource
    private RestTemplate restTemplate;
    @Value("${tencent.map.key}")
    private String key;

    /**
     * 计算驾车路线
     *
     * @param calculateDrivingLineForm 请求参数，包含起点和终点的经纬度信息
     * @return 返回驾车路线的信息，包括预计行驶时间、路线字符串和距离（以公里为单位）
     * @throws GuiguException 当请求结果为空或状态码不为0时抛出，表示地图服务调用失败
     * 此方法通过调用腾讯地图API来计算从起点到终点的驾车路线
     * 它构造了一个URL，其中包含了起点、终点和访问地图服务所需的key
     * 使用RestTemplate访问地图服务，并解析返回的JSON结果
     * 如果状态码不为0，表示请求有误或服务端错误，抛出异常
     * 否则，解析路线信息，将其封装到DrivingLineVo对象中并返回
     */
    @Override
    public DrivingLineVo calculateDrivingLine(CalculateDrivingLineForm calculateDrivingLineForm) {
        // 腾讯地图API URL模板
        String url = "https://apis.map.qq.com/ws/direction/v1/driving/?from={from}&to={to}&key={key}";

        // 构建请求参数Map，包含起点、终点和key
        Map<String,String> map = new HashMap<>();
        map.put("from",calculateDrivingLineForm.getStartPointLatitude()+","+calculateDrivingLineForm.getStartPointLongitude());
        map.put("to",calculateDrivingLineForm.getEndPointLatitude()+","+calculateDrivingLineForm.getEndPointLongitude());
        map.put("key",key);

        // 使用RestTemplate发送GET请求并接收JSON格式的响应
        JSONObject result = restTemplate.getForObject(url, JSONObject.class, map);
        // 检查响应是否为空或状态码不为0，如果异常则抛出GuiguException
        if (result == null || result.getIntValue("status") != 0) {
            throw new GuiguException(ResultCodeEnum.MAP_FAIL);
        }
        // 解析路线信息
        JSONObject route = result.getJSONObject("result").getJSONArray("routes").getJSONObject(0);
        // 封装驾车路线信息
        DrivingLineVo drivingLineVo = new DrivingLineVo();
        drivingLineVo.setDuration(route.getBigDecimal("duration"));
        drivingLineVo.setPolyline(route.getJSONArray("polyline"));
        // 将距离从米转换为公里，并四舍五入到小数点后两位
        drivingLineVo.setDistance(route.getBigDecimal("distance").
                divideToIntegralValue(new BigDecimal(1000).setScale(2, RoundingMode.HALF_UP)));
        return drivingLineVo;
    }
}
